home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-07-14 | 6.2 KB | 250 lines | [TEXT/CWIE] |
- /*************************************************************************************
-
- File: ADBUtils.cp
-
- Copyright © 1996, 1997, 1998 Apple Computer, Inc., All Rights Reserved
-
-
- You may incorporate this sample code into your applications without
- restriction, though the sample code has been provided "AS IS" and the
- responsibility for its operation is 100% yours. However, what you are
- not permitted to do is to redistribute the source as "DSC Sample Code"
- after having made changes. If you're going to re-distribute the source,
- we require that you make it clear in the source that the code was
- descended from Apple Sample Code, but that you've made changes.
-
- *************************************************************************************/
-
-
- #include "ADBUtils.h"
- #include "Common.h"
-
- #ifndef __DESKBUS__
- #include <DeskBus.h>
- #endif
-
- #if !TARGET_CPU_PPC
- #ifndef __TRAPS__
- #include <Traps.h>
- #endif
- #endif
-
- enum
- {
- kADBCommand_SendReset = 0x00,
- kADBCommand_Flush = 0x01,
- kADBCommand_Listen = 0x08,
- kADBCommand_Talk = 0x0c
- };
-
-
- // globals
- volatile UInt32 gComplete;
-
- #if TARGET_CPU_PPC
- pascal void MyADBOpCompletionRoutine(Ptr dataBuffPtr, Ptr opDataAreaPtr, long command);
-
- static RoutineDescriptor gRDMyADBOpCompletionRoutine = BUILD_ROUTINE_DESCRIPTOR(uppADBCompletionProcInfo, MyADBOpCompletionRoutine);
- static UniversalProcPtr gUPPMyADBOpCompletionRoutine = &gRDMyADBOpCompletionRoutine;
-
- pascal void MyADBOpCompletionRoutine(Ptr dataBuffPtr, Ptr opDataAreaPtr, long command)
- {
- dataBuffPtr;
- opDataAreaPtr;
- command;
-
- gComplete = true;
- }
-
- #define ADBOp_Glue ADBOp
-
- #else // !TARGET_CPU_PPC
-
- /* Because on some OSs, CFM for 68k is very sensitive to interrupts, especially
- a CFM switch called FROM and interrput, the ADB callback is in straight 68k runtime
- this involves some tweaks to bypass the CFM glue for ADBOp and callback
- */
-
- //#pragma parameter __D0 ADBOp_asm(__A0,__D0)
- asm OSErr ADBOp_asm(ADBOpBlock * pb, short commandNum);
-
- OSErr ADBOp_Glue (Ptr refCon, ADBCompletionUPP compRout, Ptr buffer, short commandNum);
- asm void MyADBOpCompletionRoutine(void);
-
- #define gUPPMyADBOpCompletionRoutine (* (UniversalProcPtr *) MyADBOpCompletionRoutine)
-
- /*
- ADBOp has a different interface for 68k assembly than for everything else
- for 68k assembly the interface is
- #pragma parameter __D0 ADBOp(__A0,__D0)
- OSErr ADBOp( ADBOpBlock * pb, short commandNum );
-
- struct ADBOpBlock {
- Ptr dataBuffPtr; // buffer: pointer to variable length data buffer
- ADBServiceRoutineUPP opServiceRtPtr; // completionProc: completion routine pointer
- Ptr opDataAreaPtr; // refCon: this field is passed as the refCon parameter to the completion routine
- };
- */
- #pragma parameter __D0 ADBOp_asm(__A0,__D0)
- asm OSErr ADBOp_asm(ADBOpBlock * pb, short commandNum)
- {
- _ADBOp
- rts
- }
-
- OSErr ADBOp_Glue (Ptr refCon, ADBCompletionUPP compRout, Ptr buffer, short commandNum)
- {
- ADBOpBlock pb;
-
- pb.dataBuffPtr = buffer;
- pb.opServiceRtPtr = compRout;
- pb.opDataAreaPtr = refCon;
-
- return ADBOp_asm(&pb, commandNum);
- }
-
- asm void MyADBOpCompletionRoutine(void)
- {
- move.l #1, (A2) // set *opDataAreaPtr
- rts
- }
-
- #endif //!TARGET_CPU_PPC
-
-
- #if TARGET_CPU_PPC
- #define Debugger_Inline() Debugger()
- #else
- void Debugger_Inline(void) = { 0xa9ff };
- #endif
-
- //
- // synchronus version of ADBOp
- //
-
- static OSErr ADBOpSync(UInt8 *buffer, short commandNum)
- {
- OSErr err;
-
- // we haven't finished the command yet
- gComplete = false;
-
- err = ADBOp_Glue((Ptr) &gComplete, gUPPMyADBOpCompletionRoutine, (Ptr) buffer, commandNum);
-
- // if there was no error wait sync for it to complete
- if (err == noErr)
- {
- while(!gComplete) { }
- }
-
- return err;
- }
-
- void ADBOp_SendResetSync(void)
- {
- OSErr err;
- short commandNum = kADBCommand_SendReset;
-
- // loop until we can send the command
- do
- {
- err = ADBOpSync(nil, commandNum);
- } while (err != noErr);
- }
-
- void ADBOp_FlushSync(ADBAddress address)
- {
- WARNING(address <= 15, "bad address passed to ADBFlush");
-
- OSErr err;
- short commandNum = address << 4 | kADBCommand_Flush;
-
- // loop until we can send the command
- do
- {
- err = ADBOpSync(nil, commandNum);
- } while (err != noErr);
- }
-
- void ADBOp_ListenSync(ADBAddress address, UInt8 reg, const ADBRegister data)
- {
- WARNING(reg <= 4, "bad register passed to ADBListenSync");
- WARNING(address <= 15, "bad address passed to ADBListenSync");
- WARNING(data[0] <= 8, "data to long passed to ADBListenSync");
- WARNING(data != nil, "nil data passed to ADBListenSync");
-
- OSErr err;
- short commandNum = address << 4 | kADBCommand_Listen | reg;
-
- // loop until we can send the command
- do
- {
- // we are converting a const UInt8 * to a UInt8 *
- // this is to the interface to ADBOpSync
- err = ADBOpSync((UInt8 *) data, commandNum);
- } while (err != noErr);
- }
-
- void ADBOp_TalkSync(ADBAddress address, UInt8 reg, ADBRegister data)
- {
- WARNING(reg <= 4, "bad register passed to ADBTalkSync");
- WARNING(address <= 15, "bad address passed to ADBTalkSync");
- WARNING(data != nil, "nil data passed to ADBTalkSync");
-
- OSErr err;
- short commandNum = address << 4 | kADBCommand_Talk | reg;
-
- // loop until we can send the command
- do
- {
- err = ADBOpSync(data, commandNum);
- } while(err != noErr);
- }
-
- void ADBOp_TalkReliableSync(ADBAddress address, UInt8 reg, ADBRegister data)
- {
- WARNING(reg <= 4, "bad register passed to ADBTalkSyncReliable");
- WARNING(address <= 15, "bad address passed to ADBTalkSyncReliable");
-
- const UInt32 numRetries = 5; // number of times we will retry on a zero length
- UInt32 emptyItr; // count of our retries
-
- for(emptyItr = 0; emptyItr < numRetries; emptyItr++)
- {
- ADBOp_TalkSync(address, reg, data);
-
- if (data[0] != 0) { break; } // read something break return
- }
- }
-
- Boolean ADBOp_ChangeHandlerIDSync(ADBAddress inAddress, UInt8 inNewHandlerID)
- {
- Boolean success;
- UInt8 data[9];
-
- // == read our register 3 ==
- ADBOp_TalkReliableSync(inAddress, 3, data);
-
- // correct length ?
- if (data[0] != 2) { return false; }
-
- // set the new handler id
- data[2] = inNewHandlerID;
-
- // == write our register 3 ==
- ADBOp_ListenSync(inAddress, 3, data);
-
- // == read our register 3 ==
- ADBOp_TalkReliableSync(inAddress, 3, data);
-
- // correct length ?
- if (data[0] != 2) { return false; }
-
- // did it change to the correct value ?
- if (data[2] == inNewHandlerID) { success = true; }
- else { success = false; }
-
- return success;
- }
-
-